<?php

namespace app\weixin\controller;

use think\Controller;
use EasyWeChat\Foundation\Application;
use think\Db;
use app\extra\push\Pusher;

class  Index extends Controller
{
    public function index()
    {
        $get = $this->request->get();
        // 微信消息推送地址验证
        if (isset($get['echostr'])) exit($get['echostr']);

        // 接收微信相关事件
        $xml = file_get_contents('php://input');
        //file_put_contents('/tmp/wx.log', $xml, FILE_APPEND);
        $xml = simplexml_load_string($xml);
        $weixin_id = $xml->ToUserName;
        // 查找这个公众号对应的配置信息
        $weixin_config = Db::table('wolive_weixin_config')->where('weixin_id', $weixin_id)->find();
        if (empty($weixin_config)) {
            return '';
        }

        $business_id = $weixin_config['business_id'];

        // config配置
        $options = [
            'app_id' => $weixin_config['appid'],
            'secret' => $weixin_config['secret'],
            'token' => $weixin_config['token'],
        ];

        if (!empty($weixin_config['aes_key'])) {
            $options['aes_key'] = $weixin_config['aes_key'];
        }

        $app = new Application($options);
        $server = $app->server;
        // 消息回复
        $server->setMessageHandler(function ($message) use ($app, $business_id) {
            // event消息忽略
            /*switch ($message['MsgType']) {
                case 'event':
                    return '';
                    break;
            }*/

            $visiter_id = ($message['FromUserName']);

            // 黑名单检查
            if (Db::table("wolive_queue")->where([
                'visiter_id'  => $visiter_id,
                'business_id' => $business_id,
                'state'       => 'in_black_list'
            ])->find()) {
                return '';
            }

            try{
                $user = $app->user->get($message['FromUserName']);
            } catch (\Exception $e) {
                $user = [
                    'headimgurl' => '/assets/images/index/wx-imghead.png',
                    'nickname'   => '访客'.str_replace(['+','/', '='] ,'' , base64_encode(pack('Nn', time(), rand(1, 65535)))),
                    'country'    => '',
                    'province'   => '',
                    'city'       => ''
                ];
            }
            $avatar = $user['headimgurl'];

            // 查看这个openid用户是否在visiter表里存在
            $visiter = Db::table('wolive_visiter')->where(['visiter_id' => $visiter_id, 'business_id' => $business_id])->find();
            // 不存在插入
            if (!$visiter) {
                Db::table('wolive_visiter')->insert([
                    'visiter_id'   => $visiter_id,
                    'visiter_name' => ($user['nickname']),
                    'channel'      => bin2hex("$visiter_id/$business_id"),
                    'avatar'       => str_replace('http://', 'https://', $avatar),
                    'ip'           => "{$user['country']} {$user['province']} {$user['city']}",
                    'from_url'     => '微信',
                    'business_id'  => $business_id,
                    'state'        => 'online',
                ]);
            }

            // 要分配的客服的数据
            $service_data = [];
            // 查找队列里上次会话的客服
            $old_online_services = Db::table('wolive_queue')->query("select s.*, q.qid from wolive_service as s join wolive_queue as q on s.service_id = q.service_id where q.visiter_id = :visiter_id and s.business_id = :business_id and s.state = 'online' order by qid desc limit 1", ['visiter_id' => $visiter_id, 'business_id' => $business_id]);
            // 不存在或者没在线，删除该visiter没用的队列数据
            if (!$old_online_services) {
                // 找一个在线的客服
                $online_services = Db::table('wolive_service')->field('service_id,avatar,business_id,groupid,nick_name,user_name,state')->where(['business_id' => $business_id, 'state' => 'online'])->select();
                // 如果没有在线的客服
                if ($online_services) {
                    // 随机找一个客服
                    $service_data = $online_services[array_rand($online_services)];
                } else {
                    // 客服都没在线，随机找一个客服
                    $all_services = Db::table('wolive_service')->field('service_id,avatar,business_id,groupid,nick_name,user_name,state')->where(['business_id' => $business_id])->select();
                    if (!$all_services) {
                        // ==== 一个客服都没有 ===
                        return '没有客服';
                    }
                    // 随机找一个客服
                    $service_data = $all_services[array_rand($all_services)];
                }
            } else {
                $service_data = current($old_online_services);
            }

            $service_id = $service_data['service_id'];

            // 删除该访客队列里其它客服的数据
            Db::table('wolive_queue')->where(['visiter_id' => $visiter_id, 'business_id' => $business_id])->where('service_id', '<>', $service_id)->delete();

            // 查看这个访客是否已经在队列里
            $queue = Db::table('wolive_queue')->where([
                'visiter_id'  => $visiter_id,
                'service_id'  => $service_id,
                'business_id' => $business_id
            ])->find();

            // 没在插入一条
            if (!$queue ) {
                Db::table('wolive_queue')->insert([
                    'visiter_id'  => $visiter_id,
                    'service_id'  => $service_id,
                    'business_id' => $business_id,
                    'state'       => 'normal',
                ]);
            } else {
                // 存在的话但不是打开状态则更新为打开normal
                if ($queue['state'] !== 'normal') {
                    Db::table('wolive_queue')->where([
                        'visiter_id' => $visiter_id,
                        'service_id' => $service_id,
                        'business_id' => $business_id
                    ])->update(['state' => 'normal']);
                }
            }

            $content = '';
            // 将消息插入到聊天记录里
            switch ($message['MsgType']) {
                case 'event':
                    // 欢迎语
                    $words = Db::table('wolive_sentence')->where("service_id", $service_id)->where('state', 'using')->find();
                    $content = $words ? $words['content'] : '您好！';
                    $app->staff->message($content)->to($visiter_id)->send();
                    return '';
                case 'text':
                    $wx_face_find = ["/::)", "/::~", "/::B", "/::|", "/:8-)", "/::<", "/::$", "/::X", "/::Z", "/::'(", "/::-|", "/::@", "/::P", "/::D", "/::O", "/::(", "/::+", "/:--b", "/::Q", "/::T", "/:,@P", "/:,@-D", "/::d", "/:,@o", "/::g", "/:|-)", "/::!", "/::L", "/::>", "/::,@", "/:,@f", "/::-S", "/:?", "/:,@x", "/:,@@", "/::8", "/:,@!", "/:!!!", "/:xx", "/:bye", "/:wipe", "/:dig", "/:handclap", "/:&-(", "/:B-)", "/:<@", "/:@>", "/::-O", "/:>-|", "/:P-(", "/::'|", "/:X-)", "/::*", "/:@x", "/:8*", "/:pd", "/:<W>", "/:beer", "/:basketb", "/:oo", "/:coffee", "/:eat", "/:pig", "/:rose", "/:fade", "/:showlove", "/:heart", "/:break", "/:cake", "/:li", "/:bome", "/:kn", "/:footb", "/:ladybug", "/:shit", "/:moon", "/:sun", "/:gift", "/:hug", "/:strong", "/:weak", "/:share", "/:v", "/:@)", "/:jj", "/:@@", "/:bad", "/:lvu", "/:no", "/:ok", "/:love", "/:<L>", "/:jump", "/:shake", "/:<O>", "/:circle", "/:kotow", "/:turn", "/:skip", "/:oY", "/:#-0", "/:hiphot", "/:kiss", "/:<&", "/:&>"];
                    $wx_face_replace = [];
                    foreach ($wx_face_find as $index => $value) {
                        $wx_face_replace[] = "<img src=\"/upload/wxface/$index.gif\"/>";
                    }
                    $content = str_replace($wx_face_find, $wx_face_replace, $message['Content']);
                    break;
                case 'image':
                    $file= $app->material_temporary->download($message['MediaId'], __DIR__ . '/../../../public/upload/images/');
                    $content = '<img onclick="getbig(this)" src="/upload/images/'.$file.'" />';
                    break;
                case 'voice':
                    $file= $app->material_temporary->download($message['MediaId'], __DIR__ . '/../../../public/upload/voices/');
                    $content = '<div style="cursor:pointer;text-align:center;" onclick="getstate(this)" data="play"><audio src="/upload/voices/'.$file.'"></audio><i class="layui-icon" style="font-size:25px;">&#xe652;</i><p>音频消息</p></div>';
                    break;
                case 'video':
                    $file= $app->material_temporary->download($message['MediaId'], __DIR__ . '/../../../public/upload/files/');
                    $thumb = $app->material_temporary->download($message['ThumbMediaId'], __DIR__ . '/../../../public/upload/files/');
                    $content = '<a msgtype="video" href="/upload/files/'.$file.'" target="_blank" style="display: block;position: relative;"><img src="/upload/files/'.$thumb.'"><i class="layui-icon" style="color:#fff;font-size: 40px;position: absolute;top: 50%;left: 50%;margin-left: -20px;margin-top: -28px;">&#xe652;</i></a>';
                    break;
                case 'location':
                    $content = "位置信息[{$message['Label']}]";
                    break;
                case 'link':
                    $content = '收到[链接消息]，暂时无法查看';
                    break;
                case 'file':
                    $content = '收到[文件消息]，暂时无法查看';
                    break;
                // ... 其它消息
                default:
                    $content = '[未知消息类型]';
                    break;
            }

            $data = [
                'visiter_id'   => $visiter_id,
                'content'      => $content,
                'business_id' => $business_id,
                'avatar'      => $avatar,
                'service_id'  => $service_id,
                'timestamp'   => time(),
                'record'      => '微信',
            ];

            $pusher = new Pusher(
                app_key,
                app_secret,
                app_id,
                ['encrypted' => false],
                ahost,
                aport
            );

            // 推送消息
            $pusher->trigger('kefu' . $service_id, 'cu-event', array('message' => $data));

            $data['direction'] = 'to_service';
            unset($data['record']);
            unset($data['avatar']);

            Db::table('wolive_chats')->insert($data);

            return '';
        });

        $response = $server->serve();
        $response->send();
    }

}
